package cn.mianshiyi.monitor;


import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author shangqing.liu
 */
public class MonitorKernel {

    private static final Lock lock = new ReentrantLock();

    private static final Map<String, MonitorCounter> monitorMap = new ConcurrentHashMap<>();

    public static ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);

    static {
        executor.scheduleAtFixedRate(() -> {
            try {
                if (monitorMap.isEmpty()) {
                    return;
                }
                monitorMap.forEach((k, v) -> {
                    System.out.println("主动推送数据,可以使用Prometheus、Open-Falcon等工具进行监控");
                    System.out.println("监控名称：" + k + "，监控值：" + v.getValueAndReset());
                });
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, 5, 30, TimeUnit.SECONDS);
    }

    /**
     * 计数器，对name指定的监控值每次增加1
     * @param name
     */
    public static void monitorCount(final String name) {
        MonitorCounter counter = monitorMap.get(name);
        if (counter == null) {
            lock.lock();
            try {
                counter = monitorMap.get(name);
                if (counter == null) {
                    counter = new AtomicCountCounter();
                    counter.setMonitorName(name);
                    monitorMap.putIfAbsent(name, counter);
                }
            } finally {
                lock.unlock();
            }
        }
        counter.addValue(1);
    }

    /**
     * 统计时间，对name指定的监控值每次增加1，时间增加
     * @param name
     */
    public static void monitorTime(final String name, final long time) {
        MonitorCounter counter = monitorMap.get(name);
        if (counter == null) {
            lock.lock();
            try {
                counter = monitorMap.get(name);
                if (counter == null) {
                    counter = new AtomicTimeCounter();
                    counter.setMonitorName(name);
                    monitorMap.putIfAbsent(name, counter);
                }
            } finally {
                lock.unlock();
            }
        }
        counter.addValue(time);
    }

}
